home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
051-075
/
scopedisk72
/
tictac
/
tictactoe.mod
< prev
next >
Wrap
Text File
|
1995-03-19
|
13KB
|
476 lines
MODULE TicTacToe;
(*
-----------------------------------------------------------------------------
Author: Robert Salesas
Program: TicTacToe V1.0
Created: 27 April 1989
Modified: ---
Comments: Link with RT.lnk
-----------------------------------------------------------------------------
*)
FROM SYSTEM IMPORT ADR, ADDRESS;
FROM ChipData IMPORT dataPtr;
FROM Intuition IMPORT WindowFlags, WindowFlagSet, WindowPtr, IDCMPFlags, IDCMPFlagSet, SmartRefresh,
CloseWindow, ImagePtr, DrawImage, Gadget, GadgetPtr, BoolGadget,
GadgHNone, ActivationFlags, ActivationFlagSet, IntuiMessage,
MenuPtr, HighNone, HighComp, ItemFlags, ItemFlagSet,
SetMenuStrip, ClearMenuStrip, SetWindowTitles, ITEMNUM, SUBNUM;
FROM EasyBeeper IMPORT Beep;
FROM EasyWindows IMPORT CreateWindow;
FROM EasyMenus IMPORT StartStrip, DisposeStrip, currentStrip, stripFailed,
nextSubFlags, nextSubLeftEdge, nextSubWidth, AddMenu, AddItem, AddSub;
FROM EasyIDCMP IMPORT ProcTable, ProcessEvents;
FROM RandomNumbers IMPORT Random;
FROM DOSProcess IMPORT Delay;
(*FROM InOut IMPORT WriteCard, WriteString, WriteLn;*)
TYPE
Coord = RECORD
X, Y, Mx, My : CARDINAL;
END;
MatrixFlags = (N, X, O, D);
MatrixRec = RECORD
XY : MatrixFlags;
Gad : CARDINAL;
END;
ModeFlags = (PP, PC, CC);
VAR
Wp : WindowPtr;
GList : ARRAY [0..9] OF Gadget;
GadCoor : ARRAY [0..8] OF Coord;
Strip : MenuPtr;
Matrix : ARRAY [0..2], [0..2] OF MatrixRec;
Turn : MatrixFlags;
GEnd : BOOLEAN;
Mode : ModeFlags;
BoardPtr : ImagePtr;
XOPtr : ARRAY [0..1] OF ImagePtr;
Table : ProcTable;
Result : INTEGER;
PROCEDURE ClearMatrix();
VAR
L1, L2 : CARDINAL;
GadID : CARDINAL;
BEGIN
GadID := 0;
FOR L1:=0 TO 2 DO
FOR L2:=0 TO 2 DO
Matrix[L1,L2].XY := N; Matrix[L1,L2].Gad := GadID;
INC(GadID);
END;
END;
DrawImage(Wp^.RPort,BoardPtr,2,10);
END ClearMatrix;
PROCEDURE CheckWin() : MatrixFlags;
VAR
L1, L2 : CARDINAL;
BEGIN
FOR L1:=0 TO 2 DO (* Check X *)
IF (Matrix[L1,0].XY # N) AND (Matrix[L1,0].XY = Matrix[L1,1].XY) AND (Matrix[L1,1].XY = Matrix[L1,2].XY) THEN
RETURN Matrix[L1,0].XY;
END;
END;
FOR L1:=0 TO 2 DO (* Check Y *)
IF (Matrix[0,L1].XY # N) AND (Matrix[0,L1].XY = Matrix[1,L1].XY) AND (Matrix[1,L1].XY = Matrix[2,L1].XY) THEN
RETURN Matrix[0,L1].XY;
END;
END;
(* Check Diagonal *)
IF (Matrix[0,0].XY = Matrix[1,1].XY) AND (Matrix[1,1].XY = Matrix[2,2].XY) THEN
RETURN Matrix[0,0].XY;
END;
IF (Matrix[0,2].XY = Matrix[1,1].XY) AND (Matrix[1,1].XY = Matrix[2,0].XY) THEN
RETURN Matrix[0,2].XY;
END;
(* Check Empty Space *)
FOR L1:=0 TO 2 DO
FOR L2:=0 TO 2 DO
IF (Matrix[L1,L2].XY = N) THEN
RETURN N;
END;
END;
END;
RETURN D;
END CheckWin;
PROCEDURE CheckNow();
BEGIN
CASE CheckWin() OF
|N : IF (Turn = X) THEN
SetWindowTitles(Wp,ADR("It's X's Turn!"),NIL);
ELSE
SetWindowTitles(Wp,ADR("It's O's Turn!"),NIL);
END;
|X : GEnd := TRUE; SetWindowTitles(Wp,ADR('"X" Wins!!!'),NIL); Beep;
|O : GEnd := TRUE; SetWindowTitles(Wp,ADR('"O" Wins!!!'),NIL); Beep;
|D : GEnd := TRUE; SetWindowTitles(Wp,ADR("It's A Draw!!!"),NIL); Beep;
END;
END CheckNow;
PROCEDURE Computer(Peg : MatrixFlags);
VAR
Mx, My,
L1, L2,
Gad : CARDINAL;
PROCEDURE FreeSpace() : BOOLEAN;
BEGIN
FOR L1:=0 TO 2 DO
FOR L2:=0 TO 2 DO
IF (Matrix[L1,L2].XY = N) THEN
RETURN TRUE;
END;
END;
END;
RETURN FALSE;
END FreeSpace;
PROCEDURE TwoInARow(Flag : MatrixFlags) : BOOLEAN;
VAR
L1 : CARDINAL;
BEGIN
FOR L1:=0 TO 2 DO (* Check X *)
IF (Matrix[0,L1].XY = Flag) AND (Matrix[2,L1].XY = N) AND
(Matrix[0,L1].XY = Matrix[1,L1].XY) THEN
Mx := 2; My := L1;
RETURN TRUE;
END;
IF (Matrix[2,L1].XY = Flag) AND (Matrix[0,L1].XY = N) AND
(Matrix[1,L1].XY = Matrix[2,L1].XY) THEN
Mx := 0; My := L1;
RETURN TRUE;
END;
IF (Matrix[0,L1].XY = Flag) AND (Matrix[1,L1].XY = N) AND
(Matrix[0,L1].XY = Matrix[2,L1].XY) THEN
Mx := 1; My := L1;
RETURN TRUE;
END;
END;
FOR L1:=0 TO 2 DO (* Check Y *)
IF (Matrix[L1,0].XY = Flag) AND (Matrix[L1,2].XY = N) AND
(Matrix[L1,0].XY = Matrix[L1,1].XY) THEN
Mx := L1; My := 2;
RETURN TRUE;
END;
IF (Matrix[L1,2].XY = Flag) AND (Matrix[L1,0].XY = N) AND
(Matrix[L1,1].XY = Matrix[L1,2].XY) THEN
Mx := L1; My := 0;
RETURN TRUE;
END;
IF (Matrix[L1,0].XY = Flag) AND (Matrix[L1,1].XY = N) AND
(Matrix[L1,0].XY = Matrix[L1,2].XY) THEN
Mx := L1; My := 1;
RETURN TRUE;
END;
END;
(* Check \ *)
IF (Matrix[0,0].XY = Flag) AND (Matrix[2,2].XY = N) AND
(Matrix[0,0].XY = Matrix[1,1].XY) THEN
Mx := 2; My := 2;
RETURN TRUE;
END;
IF (Matrix[2,2].XY = Flag) AND (Matrix[0,0].XY = N) AND
(Matrix[1,1].XY = Matrix[2,2].XY) THEN
Mx := 0; My := 0;
RETURN TRUE;
END;
IF (Matrix[0,0].XY = Flag) AND (Matrix[1,1].XY = N) AND
(Matrix[0,0].XY = Matrix[2,2].XY) THEN
Mx := 1; My := 1;
RETURN TRUE;
END;
(* Check / *)
IF (Matrix[0,2].XY = Flag) AND (Matrix[2,0].XY = N) AND
(Matrix[0,2].XY = Matrix[1,1].XY) THEN
Mx := 2; My := 0;
RETURN TRUE;
END;
IF (Matrix[2,0].XY = Flag) AND (Matrix[0,2].XY = N) AND
(Matrix[1,1].XY = Matrix[2,0].XY) THEN
Mx := 0; My := 2;
RETURN TRUE;
END;
IF (Matrix[0,2].XY = Flag) AND (Matrix[1,1].XY = N) AND
(Matrix[0,2].XY = Matrix[2,0].XY) THEN
Mx := 1; My := 1;
RETURN TRUE;
END;
RETURN FALSE;
END TwoInARow;
PROCEDURE RandomSpot();
BEGIN
LOOP;
Mx := Random(3); My := Random(3);
IF (Matrix[Mx,My].XY = N) THEN
EXIT;
END;
END;
END RandomSpot;
PROCEDURE PlacePeg();
BEGIN
Matrix[Mx,My].XY := Peg;
Gad := Matrix[Mx,My].Gad;
DrawImage(Wp^.RPort,XOPtr[ORD(Peg) - 1],GadCoor[Gad].X + 4,GadCoor[Gad].Y + 1);
END PlacePeg;
BEGIN
Mx := 0; My := 0;
IF FreeSpace() THEN
IF (Matrix[1,1].XY = N) THEN
Mx := 1; My := 1;
ELSIF NOT TwoInARow(Peg) THEN
CASE Peg OF
|O : IF NOT TwoInARow(X) THEN RandomSpot; END;
|X : IF NOT TwoInARow(O) THEN RandomSpot; END;
END;
END;
PlacePeg;
END;
END Computer;
PROCEDURE HandleCloseWindow(VAR Message : IntuiMessage) : INTEGER;
BEGIN
RETURN -1;
END HandleCloseWindow;
PROCEDURE HandleMenus(VAR Message : IntuiMessage; MenuNum : CARDINAL) : INTEGER;
VAR
Item, Sub : CARDINAL;
L1, L2 : CARDINAL;
BEGIN
Item := ITEMNUM(MenuNum) + 1; Sub := SUBNUM(MenuNum) + 1;
IF (Item = 3) THEN
RETURN -1;
ELSIF (Item = 1) THEN
ClearMatrix; Turn := X; GEnd := FALSE;
CASE Sub OF
|1 : Mode := PP; SetWindowTitles(Wp,ADR("Player/Player"),NIL);
|2 : Mode := PC; SetWindowTitles(Wp,ADR("Player/Computer"),NIL);
|3 : Mode := CC; SetWindowTitles(Wp,ADR("Computer/Computer"),NIL);
RETURN 1
END;
END;
RETURN NIL;
END HandleMenus;
PROCEDURE HandleGadgets(VAR Message : IntuiMessage; Gadget : GadgetPtr) : INTEGER;
VAR
Gad : CARDINAL;
Mx, My : CARDINAL;
PROCEDURE Player();
BEGIN
IF (Turn = O) THEN
Matrix[Mx,My].XY := O;
DrawImage(Wp^.RPort,XOPtr[1],GadCoor[Gad].X + 4,GadCoor[Gad].Y + 1);
ELSE
Matrix[Mx,My].XY := X;
DrawImage(Wp^.RPort,XOPtr[0],GadCoor[Gad].X + 4,GadCoor[Gad].Y + 1);
END;
END Player;
BEGIN
Gad := Gadget^.GadgetID;
IF (Gad = 9) THEN
ClearMatrix; Turn := X; GEnd := FALSE;
CASE Mode OF
|PP : SetWindowTitles(Wp,ADR("Player/Player"),NIL);
|PC : SetWindowTitles(Wp,ADR("Player/Computer"),NIL);
|CC : SetWindowTitles(Wp,ADR("Computer/Computer"),NIL);
RETURN 1
END;
RETURN NIL;
ELSIF GEnd OR (Mode = CC) THEN
RETURN NIL;
END;
Mx := GadCoor[Gad].Mx; My := GadCoor[Gad].My;
IF (Matrix[Mx,My].XY # N) THEN
Beep;
ELSE
CASE Mode OF
|PP : Player;
IF (Turn = X) THEN
Turn := O;
ELSE
Turn := X;
END;
CheckNow
|PC : Player; CheckNow;
IF NOT GEnd THEN
Computer(O); CheckNow;
END;
END;
END;
RETURN NIL;
END HandleGadgets;
PROCEDURE PlayCC();
BEGIN
WHILE NOT GEnd DO
Computer(X); CheckNow;
IF NOT GEnd THEN
Computer(O); CheckNow;
END;
END;
END PlayCC;
PROCEDURE Init(VAR Wp : WindowPtr; VAR Strip : MenuPtr;
VAR GList : ARRAY OF Gadget; GadCoor : ARRAY OF Coord) : BOOLEAN;
PROCEDURE SetGadgets();
VAR
Gad : CARDINAL;
BEGIN
FOR Gad := 0 TO 8 DO
WITH GList[Gad] DO
NextGadget := ADR(GList[Gad + 1]);
LeftEdge := GadCoor[Gad].X;
TopEdge := GadCoor[Gad].Y;
Width := 47;
Height := 23;
Flags := GadgHNone;
Activation := ActivationFlagSet{RelVerify};
GadgetType := BoolGadget;
GadgetID := Gad;
END;
END;
WITH GList[9] DO
NextGadget := NIL;
LeftEdge := 50;
TopEdge := 14;
Width := 126;
Height := 19;
Flags := GadgHNone;
Activation := ActivationFlagSet{RelVerify};
GadgetType := BoolGadget;
GadgetID := 9;
END;
END SetGadgets;
PROCEDURE OpenWindow();
BEGIN
Wp := CreateWindow(202,39,236,120,"Player/Player",
IDCMPFlagSet{GadgetUp, CloseWindowFlag, MenuPick},
WindowFlagSet{WindowDepth, WindowDrag, WindowClose,
NoCareRefresh, Activate} + SmartRefresh,
NIL,ADR(GList));
END OpenWindow;
PROCEDURE SetMenus();
BEGIN
StartStrip;
AddMenu("Project ",100);
nextSubLeftEdge := 70; nextSubWidth := 232;
AddItem("New Game",0C);
AddSub("Player Vs. Player ","1");
AddSub("Player Vs. Computer ","2");
AddSub("Computer Vs. Computer ","3");
AddItem("About...",0C);
nextSubWidth := 100;
nextSubFlags := ItemFlagSet{ItemText, ItemEnabled} + HighNone;
AddSub(" Tic Tac Toe V1.00",0C);
AddSub(" © Copyright 1989",0C);
AddSub(" By Robert Salesas",0C);
AddSub(0C,0C);
AddSub(" Developed using M2Sprint ",0C);
AddSub(" for the Amiga.",0C);
AddSub(" M2S Inc., Dallas, Texas.",0C);
AddItem("Quit","Q");
IF NOT stripFailed THEN
Strip := currentStrip;
SetMenuStrip(Wp,Strip);
END;
END SetMenus;
BEGIN
SetGadgets;
OpenWindow;
IF (Wp # NIL) THEN
SetMenus;
IF (Strip # NIL) THEN
DrawImage(Wp^.RPort,BoardPtr,2,10);
RETURN TRUE;
END;
END;
RETURN FALSE;
END Init;
PROCEDURE InitVars();
BEGIN
BoardPtr := ADR(dataPtr^[0]);
XOPtr[1] := ADR(dataPtr^[1]); XOPtr[0] := ADR(dataPtr^[2]);
Turn := X;
END InitVars;
PROCEDURE InitProcTable(VAR Table : ProcTable);
BEGIN
WITH Table DO
WaitForEvent := TRUE;
CloseWindow := HandleCloseWindow;
MenuPick := HandleMenus;
GadgetUp := HandleGadgets;
END;
END InitProcTable;
PROCEDURE InitGadCoor(VAR GadCoor : ARRAY OF Coord);
BEGIN
GadCoor[0].X := 39; GadCoor[0].Y := 35; GadCoor[0].Mx := 0; GadCoor[0].My := 0;
GadCoor[1].X := 91; GadCoor[1].Y := 35; GadCoor[1].Mx := 0; GadCoor[1].My := 1;
GadCoor[2].X := 139; GadCoor[2].Y := 35; GadCoor[2].Mx := 0; GadCoor[2].My := 2;
GadCoor[3].X := 39; GadCoor[3].Y := 61; GadCoor[3].Mx := 1; GadCoor[3].My := 0;
GadCoor[4].X := 91; GadCoor[4].Y := 61; GadCoor[4].Mx := 1; GadCoor[4].My := 1;
GadCoor[5].X := 139; GadCoor[5].Y := 61; GadCoor[5].Mx := 1; GadCoor[5].My := 2;
GadCoor[6].X := 39; GadCoor[6].Y := 85; GadCoor[6].Mx := 2; GadCoor[6].My := 0;
GadCoor[7].X := 91; GadCoor[7].Y := 85; GadCoor[7].Mx := 2; GadCoor[7].My := 1;
GadCoor[8].X := 139; GadCoor[8].Y := 85; GadCoor[8].Mx := 2; GadCoor[8].My := 2;
END InitGadCoor;
BEGIN
InitGadCoor(GadCoor);
InitProcTable(Table);
InitVars;
IF Init(Wp,Strip,GList,GadCoor) THEN
REPEAT
Result := ProcessEvents(Wp,Table);
IF (Result = 1) THEN
PlayCC;
END;
UNTIL Result = -1;
ClearMenuStrip(Wp); DisposeStrip(Strip);
CloseWindow(Wp);
END;
END TicTacToe.